﻿
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Linq.Expressions;

namespace Anno.Repository
{
    public static class SqlSugarSetup
	{
        public static List<ConnectionConfig> ConnectConfigList { get; set; } = new List<ConnectionConfig>();
        public static ConnectionStringsOptions ConnectionStringsConfig { get; set; }
        public static void SqlSugarConfigure(this IServiceCollection services)
        {
            //添加options
            //services.AddOptions();
            //services.Configure<SiteConfig>(Configuration.GetSection("SiteConfig"));
            //services.AddConfigurableOptions<ConnectionStringsOptions>();
            ConnectionStringsConfig = new ConnectionStringsOptions().Init();
            services.AddSingleton(ConnectionStringsConfig);

            #region 配置sqlsuagr
            ConnectConfigList = new List<ConnectionConfig>();
            //数据库序号从0开始,默认数据库为0
            var config = ConnectionStringsConfig;// new ConnectionStringsOptions().Init();//Loader.IocLoader.Resolve<ConnectionStringsOptions>();// 
            //默认数据库
            ConnectConfigList.Add(new ConnectionConfig
            {
                ConnectionString = config.DefaultDbString,
                DbType = (DbType)Convert.ToInt32(Enum.Parse(typeof(DbType), config.DefaultDbType)),
                IsAutoCloseConnection = true,
                ConfigId = config.DefaultDbNumber,
                InitKeyType = InitKeyType.Attribute,
                MoreSettings = new ConnMoreSettings()
                {
                    IsAutoRemoveDataCache = true//自动清理缓存

                },
                ConfigureExternalServices = new ConfigureExternalServices()
                {
                    EntityNameService = (type, entity) =>
                    {
                        var attributes = type.GetCustomAttributes(true);
                        if (attributes.Any(it => it is TableAttribute))
                        {
                            entity.DbTableName = (attributes.First(it => it is TableAttribute) as TableAttribute).Name;
                        }
                    },
                    EntityService = (type, column) =>
                    {
                        var attributes = type.GetCustomAttributes(true);
						if (attributes.Any(it => it is KeyAttribute))// by attribute set primarykey
						{
							column.IsPrimarykey = true; //有哪些特性可以看 1.2 特性明细
						}
						if (attributes.Any(it => it is ColumnAttribute))
                        {
                            column.DbColumnName = (attributes.First(it => it is ColumnAttribute) as ColumnAttribute).Name;
                        }
                    }
                }

            });
            if (config.DbConfigs == null)
                config.DbConfigs = new List<DbConfig>();
            //业务数据库集合
            foreach (var item in config.DbConfigs)
            {
                //防止数据库重复，导致的事务异常
                if (ConnectConfigList.Any(a => a.ConfigId == (dynamic)item.DbNumber))
				{
                    continue;
				}
                ConnectConfigList.Add(new ConnectionConfig
                {
                    ConnectionString = item.DbString,
                    DbType = (DbType)Convert.ToInt32(Enum.Parse(typeof(DbType), item.DbType)),
                    IsAutoCloseConnection = true,
                    ConfigId = item.DbNumber,
                    InitKeyType = InitKeyType.Attribute,
                    MoreSettings = new ConnMoreSettings()
                    {
                        IsAutoRemoveDataCache = true//自动清理缓存
                    }
                });
            }
            //List<Type> types = App.EffectiveTypes.Where(a => !a.IsAbstract && a.IsClass && a.GetCustomAttributes(typeof(SugarTable), true)?.FirstOrDefault() != null).ToList();
            //sugar action
            Action<ISqlSugarClient, List<ConnectionConfig>> configure = (db, connectConfigList) =>
            {
                connectConfigList.ForEach(config => {
                string temp = config.ConfigId;
                    var _db = db.AsTenant().GetConnection(temp);
                    _db.CurrentConnectionConfig.ConfigureExternalServices = new ConfigureExternalServices()
                     {
                         DataInfoCacheService = new SqlSugarCache()//配置我们创建的缓存类
                     };
                    //执行超时时间
                    _db.Ado.CommandTimeOut = 30;
                    _db.Aop.OnLogExecuting = (sql, pars) =>
                    {
                        if (sql.StartsWith("SELECT"))
                        {
                            Console.ForegroundColor = ConsoleColor.Green;
                        }
                        if (sql.StartsWith("UPDATE") || sql.StartsWith("INSERT"))
                        {
                            Console.ForegroundColor = ConsoleColor.White;
                        }
                        if (sql.StartsWith("DELETE"))
                        {
                            Console.ForegroundColor = ConsoleColor.Blue;
                        }
                        //App.PrintToMiniProfiler("SqlSugar", "Info", sql + "\r\n" + _db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
                        Console.WriteLine("Sql:" + "\r\n\r\n" + UtilMethods.GetSqlString(db.CurrentConnectionConfig.DbType, sql, pars));
                       // App.PrintToMiniProfiler("SqlSugar", "Info", UtilMethods.GetSqlString(db.CurrentConnectionConfig.DbType, sql, pars));
                    };


                    //_db.Aop.DataExecuting = (oldValue, entityInfo) =>
                    //{
                    //    // 新增操作
                    //    if (entityInfo.OperationType == DataFilterType.InsertByObject)
                    //    {
                    //        // 主键(long)-赋值雪花Id
                    //        if (entityInfo.EntityColumnInfo.IsPrimarykey && entityInfo.EntityColumnInfo.PropertyInfo.PropertyType == typeof(long)) {
                    //            var id = ((dynamic)entityInfo.EntityValue).Id;
                    //            if (id == null || id == 0)
                    //                entityInfo.SetValue(Yitter.IdGenerator.YitIdHelper.NextId());
                    //        }
                               

                    //        if (entityInfo.PropertyName == "CreatedTime")
                    //            entityInfo.SetValue(DateTime.Now);
                    //        if (App.User != null)
                    //        {
                    //            if (entityInfo.PropertyName == "TenantId")
                    //            {
                    //                var tenantId = ((dynamic)entityInfo.EntityValue).TenantId;
                    //                if (tenantId == null || tenantId == 0)
                    //                    entityInfo.SetValue(App.User.FindFirst(ClaimConst.TENANT_ID)?.Value);
                    //            }
                    //            if (entityInfo.PropertyName == "CreatedUserId") {
                    //                var createUserId = ((dynamic)entityInfo.EntityValue).CreatedUserId;
                    //                if (createUserId == null || createUserId == 0)
                    //                    entityInfo.SetValue(App.User.FindFirst(ClaimConst.CLAINM_USERID)?.Value);
                    //            }
                                   
                    //            if (entityInfo.PropertyName == "CreatedUserName")
                    //                entityInfo.SetValue(App.User.FindFirst(ClaimConst.CLAINM_NAME)?.Value);
                    //            //if (entityInfo.PropertyName == "CreateOrgId")
                    //            //    entityInfo.SetValue(App.User.FindFirst(ClaimConst.OrgId)?.Value);
                    //        }
                    //    }
                    //    // 更新操作
                    //    if (entityInfo.OperationType == DataFilterType.UpdateByObject)
                    //    {
                    //        if (entityInfo.PropertyName == "UpdatedTime")
                    //            entityInfo.SetValue(DateTime.Now);
                    //        if (entityInfo.PropertyName == "UpdatedUserId")
                    //            entityInfo.SetValue(App.User?.FindFirst(ClaimConst.CLAINM_USERID)?.Value);
                    //        if (entityInfo.PropertyName == "UpdatedUserName")
                    //            entityInfo.SetValue(App.User?.FindFirst(ClaimConst.CLAINM_NAME)?.Value);
                    //    }
                    //};

                });
            };
            services.AddSqlSugarRepository(ConnectConfigList, configure);
            #endregion

        }
        /// <summary>
        /// 添加 SqlSugar 拓展
        /// </summary>
        /// <param name="services"></param>
        /// <param name="config"></param>
        /// <param name="buildAction"></param>
        /// <returns></returns>
        public static IServiceCollection AddSqlSugarClient(this IServiceCollection services, ConnectionConfig config, Action<ISqlSugarClient, List<ConnectionConfig>> buildAction = default)
        {
            var list = new List<ConnectionConfig>();
            list.Add(config);
            return services.AddSqlSugarRepository(list, buildAction);
        }

        /// <summary>
        /// 添加 SqlSugar 拓展
        /// </summary>
        /// <param name="services"></param>
        /// <param name="configs"></param>
        /// <param name="buildAction"></param>
        /// <returns></returns>
        public static IServiceCollection AddSqlSugarRepository(this IServiceCollection services, List<ConnectionConfig> configs, Action<ISqlSugarClient, List<ConnectionConfig>> buildAction = default)
        {
            // 注册 SqlSugar 客户端
            services.AddScoped<ISqlSugarClient>(u =>
            {
                var db = new SqlSugarClient(configs);
                buildAction?.Invoke(db, configs);
                return db;
            });
            // 注册非泛型仓储
            services.AddScoped<ISqlSugarRepository, SqlSugarRepository>();
            // 注册 SqlSugar 仓储
            services.AddScoped(typeof(ISqlSugarRepository<>), typeof(SqlSugarRepository<>));

            return services;
        }
    }
}
